package repository

import (
	"api-gateway-center/domain/manage/model"
	"api-gateway-center/domain/manage/repository"
	"api-gateway-center/infrastructure/po"
	"gorm.io/gorm"
	"time"
)

type configManageRepository struct {
	db *gorm.DB
}

func (this *configManageRepository) QueryGatewayServerDetailList() ([]*model.GatewayServerDetailVO, error) {
	var gatewayServerDetails []po.GatewayServerDetail
	if err := this.db.Find(&gatewayServerDetails).Error; err != nil {
		return nil, err
	}
	var gatewayServerDetailVos []*model.GatewayServerDetailVO
	for _, serverDetail := range gatewayServerDetails {
		serverDetailVO := model.NewGatewayServerDetailVO(serverDetail.GroupId, serverDetail.GatewayId, serverDetail.GatewayName, serverDetail.GatewayAddress, serverDetail.Status)
		gatewayServerDetailVos = append(gatewayServerDetailVos, serverDetailVO)
	}
	return gatewayServerDetailVos, nil
}

func NewConfigManageRepository(db *gorm.DB) repository.ConfigManageRepository {
	return &configManageRepository{db: db}
}

func (this *configManageRepository) QueryGatewayServerList() ([]model.GatewayServerVO, error) {
	var gatewayServers []po.GatewayServer
	var gatewayServerVoList []model.GatewayServerVO
	if err := this.db.Find(&gatewayServers).Error; err != nil {
		return nil, err
	}
	for _, server := range gatewayServers {
		gatewayServerVo := model.NewGatewayServerVo(server.GroupId, server.GroupName)
		gatewayServerVoList = append(gatewayServerVoList, gatewayServerVo)
	}
	return gatewayServerVoList, nil
}

func (this *configManageRepository) RegisterGatewayServerNode(groupId, gatewayId, gatewayName, gatewayAddress string, status int) error {
	gatewayServerDetail := po.GatewayServerDetail{
		GroupId:        groupId,
		GatewayId:      gatewayId,
		GatewayName:    gatewayName,
		GatewayAddress: gatewayAddress,
		Status:         status,
		CreatedAt:      time.Now(),
		UpdatedAt:      time.Now(),
	}
	return this.db.Create(&gatewayServerDetail).Error
}

func (this *configManageRepository) QueryGatewayServerDetail(gatewayId, gatewayAddress string) (*model.GatewayServerDetailVO, error) {
	var gatewayServerDetail po.GatewayServerDetail
	if err := this.db.Where("gateway_id = ? AND gateway_address = ?", gatewayId, gatewayAddress).First(&gatewayServerDetail).Error; err != nil {
		return nil, err
	}
	var gatewayServerDetailVO model.GatewayServerDetailVO
	model.NewGatewayServerDetailVO(gatewayServerDetail.GroupId, gatewayServerDetail.GatewayId,
		gatewayServerDetail.GatewayName,
		gatewayServerDetail.GatewayAddress,
		gatewayServerDetail.Status)
	return &gatewayServerDetailVO, nil
}

func (this *configManageRepository) UpdateGatewayStatus(gatewayId, gatewayAddress string, available int) error {
	return this.db.Model(&po.GatewayServerDetail{}).Where("gateway_id = ? AND gateway_address = ?", gatewayId, gatewayAddress).Update("status", available).Error
}

func (this *configManageRepository) QueryGatewayDistributionSystemIdList(gatewayId string) ([]string, error) {
	var systemIds []string
	if err := this.db.Table("gateway_distribution").Select("system_id").Where("gateway_id = ?", gatewayId).Find(&systemIds).Error; err != nil {
		return nil, err
	}
	return systemIds, nil
}

func (this *configManageRepository) QueryApplicationSystemVOList(systemIdList []string) ([]*model.ApplicationSystemVO, error) {
	var applicationSystems []po.ApplicationSystem
	if err := this.db.Where("system_id IN ?", systemIdList).Find(&applicationSystems).Error; err != nil {
		return nil, err
	}
	var applicationSystemsVos []*model.ApplicationSystemVO
	for _, applicationSystem := range applicationSystems {
		applicationSystemVO := model.NewApplicationSystemVO(applicationSystem.SystemId,
			applicationSystem.SystemName,
			applicationSystem.SystemType,
			applicationSystem.SystemRegistry,
		)
		applicationSystemsVos = append(applicationSystemsVos, &applicationSystemVO)
	}
	return applicationSystemsVos, nil
}

func (this *configManageRepository) QueryApplicationInterfaceList(systemId string) ([]*model.ApplicationInterfaceVO, error) {
	var applicationInterfaces []po.ApplicationInterface
	if err := this.db.Where("system_id = ?", systemId).Find(&applicationInterfaces).Error; err != nil {
		return nil, err
	}
	var applicationInterfaceVos []*model.ApplicationInterfaceVO
	for _, applicationInterface := range applicationInterfaces {
		applicationInterfaceVO := model.NewApplicationInterfaceVO(applicationInterface.SystemId,
			applicationInterface.InterfaceId,
			applicationInterface.InterfaceName,
			applicationInterface.InterfaceVersion,
		)
		applicationInterfaceVos = append(applicationInterfaceVos, &applicationInterfaceVO)
	}
	return applicationInterfaceVos, nil
}

func (this *configManageRepository) QueryApplicationInterfaceMethodList(systemId, interfaceId string) ([]*model.ApplicationInterfaceMethodVO, error) {
	var applicationInterfaceMethods []po.ApplicationInterfaceMethod
	if err := this.db.Where("system_id = ? AND interface_id = ?", systemId, interfaceId).Find(&applicationInterfaceMethods).Error; err != nil {
		return nil, err
	}

	var applicationInterfaceMethodVos []*model.ApplicationInterfaceMethodVO
	for _, interfaceMethod := range applicationInterfaceMethods {
		interfaceMethodVO := model.NewApplicationInterfaceMethodVO(interfaceMethod.SystemId,
			interfaceMethod.InterfaceId,
			interfaceMethod.MethodId,
			interfaceMethod.MethodName,
			interfaceMethod.ParameterType,
			interfaceMethod.Uri,
			interfaceMethod.HttpCommandType,
			interfaceMethod.Auth)
		applicationInterfaceMethodVos = append(applicationInterfaceMethodVos, &interfaceMethodVO)
	}
	return applicationInterfaceMethodVos, nil
}

func (this *configManageRepository) QueryGatewayDistribution(systemId string) (string, error) {
	var distribution string
	if err := this.db.Table("gateway_distribution").Select("gateway_id").Where("system_id = ?", systemId).Scan(&distribution).Error; err != nil {
		return "", err
	}
	return distribution, nil
}
